package com.molichuxing.gateway.bff.car.services.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.gateway.bff.car.entity.request.create.MaintenanceLogCreateVo;
import com.molichuxing.gateway.bff.car.entity.response.MaintenanceAppNewVo;
import com.molichuxing.gateway.bff.car.entity.response.MaintenanceAppVo;
import com.molichuxing.gateway.bff.car.entity.response.MaintenanceLogAppVo;
import com.molichuxing.gateway.bff.car.entity.response.MaintenanceLogVo;
import com.molichuxing.gateway.bff.car.entity.response.MaintenanceVo;
import com.molichuxing.gateway.bff.car.services.MaintenanceBffService;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.services.business.dto.response.CarOrderBizDto;
import com.molichuxing.services.business.dto.response.OrderDeliveryBizDto;
import com.molichuxing.services.business.service.OrderBizService;
import com.molichuxing.services.infrastructure.dto.request.create.MaintenanceLogCreateDto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.IovMileageDto;
import com.molichuxing.services.infrastructure.dto.response.MaintenanceConfigDto;
import com.molichuxing.services.infrastructure.dto.response.MaintenanceDto;
import com.molichuxing.services.infrastructure.dto.response.MaintenanceLogDto;
import com.molichuxing.services.infrastructure.dto.response.StoreDto;
import com.molichuxing.services.infrastructure.service.CarService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.MaintenanceConfigService;
import com.molichuxing.services.infrastructure.service.MaintenanceLogService;
import com.molichuxing.services.infrastructure.service.MaintenanceService;
import com.molichuxing.services.infrastructure.service.OrderDeliveryService;
import com.molichuxing.services.infrastructure.service.StoreService;
import com.molichuxing.services.property.MaintenanceRejectEnum;
import com.molichuxing.services.property.MaintenanceStatusEnum;
import com.molichuxing.services.property.MaintenanceTypeEnum;
import com.molichuxing.services.property.MaintenanceUserTypeEnum;

/**
 * @Author: renzhengyu
 * @Description:
 * @Date: Created in 10:24 2019/9/26
 * @Modified By:
 **/
@Service("maintenanceBffService")
public class MaintenanceBffServiceImpl implements MaintenanceBffService {
    private static final Logger logger = LoggerFactory.getLogger(MaintenanceBffServiceImpl.class);

    @Resource
    private CarService carService;
    @Resource
    private OrderBizService orderBizService;
    @Resource
    private MaintenanceLogService maintenanceLogService;
    @Resource
    private StoreService storeService;
    @Resource
    private MaintenanceService maintenanceService;
    @Resource
    private MaintenanceConfigService maintenanceConfigService;
    @Resource
    private IovCarService iovCarService;
    @Resource
    private OrderDeliveryService orderDeliveryService;

    @Override
    public Boolean createMaintenanceLog(MaintenanceLogCreateVo maintenanceLogCreateVo) throws Exception {

        //获取当前登录用户
        Integer userId = RequestAttrUtil.getCurrentUserId();
        if(null == userId){
            throw new Exception("用户未登录");
        }
        //根据车牌查询车辆id
        CarDto carDto = carService.getByVinLicencePlate(null,maintenanceLogCreateVo.getLicencePlate());
        if(null == carDto ){
            throw new Exception("车牌不存在");
        }
        MaintenanceLogCreateDto maintenanceLogCreateDto = new MaintenanceLogCreateDto();
        BeanUtils.copyProperties(maintenanceLogCreateVo,maintenanceLogCreateDto);
        //查询当前车辆是否关联用车中的订单
        CarOrderBizDto carOrderBizDto = orderBizService.getUseOrderByCar(carDto.getId(),userId);
        if(null != carOrderBizDto){
            maintenanceLogCreateDto.setOrderCode(carOrderBizDto.getOrderCode());
        }
        maintenanceLogCreateDto.setUserType(MaintenanceUserTypeEnum.USER.getValue());
        maintenanceLogCreateDto.setUserId(userId);
        maintenanceLogCreateDto.setCarId(carDto.getId());
        maintenanceLogCreateDto.setSettlementUrl(JSON.toJSONString(maintenanceLogCreateVo.getSettlementUrlList()));
        maintenanceLogCreateDto.setSubmitMemberId(userId);
        maintenanceLogCreateDto.setMaintainableDate(DateUtil.parseDate(maintenanceLogCreateVo.getMaintainableDate()).atStartOfDay());
        maintenanceLogCreateDto.setActualMaintainDate(DateUtil.parseDate(maintenanceLogCreateVo.getActualMaintainDate()));
        maintenanceLogCreateDto.setSubmitDate(LocalDateTime.now());
        maintenanceLogCreateDto.setPurchaseDate(carDto.getPurchaseDate());
        maintenanceLogCreateDto.setStatus(MaintenanceStatusEnum.AUDITED.getValue());
        if(null == maintenanceLogCreateVo.getId()){
            //新增
            int ret = maintenanceLogService.createMaintenanceLog(maintenanceLogCreateDto);
            if(ret < 0){
                logger.error("新建保养信息失败");
                throw new Exception("新建保养信息失败");
            }
            maintenanceService.updateMaintenanceStatusById(maintenanceLogCreateVo.getMaintenanceId(),MaintenanceStatusEnum.AUDITED);
        }else{
            MaintenanceDto maintenanceDto = maintenanceService.getMaintenance(maintenanceLogCreateVo.getMaintenanceId());
            if(null == maintenanceDto){
                throw new Exception("新建保养信息失败");
            }
            if(MaintenanceStatusEnum.AUDIT_PASS.getValue() == maintenanceDto.getStatus()){
                throw new Exception("无效操作，该保养凭证系统已处理，\n" +
                        "\n" +
                        "如有疑问请联系客服");
            }
            //修改
            int ret = maintenanceLogService.updateById(maintenanceLogCreateDto);
            if(ret < 0){
                logger.error("修改保养信息失败");
                throw new Exception("修改保养信息失败");
            }
            maintenanceService.updateMaintenanceStatusById(maintenanceDto.getId(),MaintenanceStatusEnum.AUDITED);

        }
        return true;
    }

    @Override
    public Boolean checkStateMaintenanceLog(Integer maintenanceLogId) throws Exception {

        MaintenanceLogDto maintenanceLogDto = maintenanceLogService.getMaintenanceLogById(maintenanceLogId);
        if(null == maintenanceLogDto){
            throw new Exception("非法入参");
        }
        return maintenanceLogDto.getStatus().equals(MaintenanceStatusEnum.AUDIT_PASS.getValue())? true:false;
    }


    @Override
    public MaintenanceLogVo maintenanceLogDetail(Integer maintenanceLogId) throws Exception {

        MaintenanceLogDto maintenanceLogDto = maintenanceLogService.getMaintenanceLogById(maintenanceLogId);
        if(null == maintenanceLogDto ){
            throw new Exception("非法入参");
        }
        CarDto carDto = carService.getCarById(maintenanceLogDto.getCarId());
        if(null == carDto ){
            throw new Exception("车辆不存在");
        }

        //查询该车辆的提车时间
        OrderDeliveryBizDto orderDeliveryDto = orderBizService.getDelivery(maintenanceLogDto.getOrderCode());
        if(null == orderDeliveryDto){
            throw new Exception("提车信息为空");
        }
        MaintenanceLogVo maintenanceLogVo = new MaintenanceLogVo();
        BeanUtils.copyProperties(maintenanceLogDto,maintenanceLogVo);
        maintenanceLogVo.setDeliveryTime(LocalDateTime.now().minusYears(1).isBefore(orderDeliveryDto.getDeliveryTime())?orderDeliveryDto.getDeliveryTime():LocalDateTime.now().minusYears(1));
        maintenanceLogVo.setTypeStr(MaintenanceTypeEnum.getName(maintenanceLogDto.getType()));
        maintenanceLogVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceLogDto.getStatus()));
        maintenanceLogVo.setSettlementUrlList(JSON.parseArray(maintenanceLogDto.getSettlementUrl(),String.class));
        maintenanceLogVo.setLicencePlate(carDto.getLicencePlate());
        maintenanceLogVo.setStoreId(orderDeliveryDto.getStoreId());
        //调车联网获取当前车辆已行驶里程
        maintenanceLogVo.setNowMileage(new BigDecimal(getMileageByVin(carDto.getVin())));
        return maintenanceLogVo;
    }

    @Override
    public MaintenanceAppVo getMaintenanceAppVoPage(Integer resultType, Integer pageNum, Integer pageSize) throws Exception {
        MaintenanceAppVo maintenanceAppVo = new MaintenanceAppVo();
        //获取当前登录的用户id
        Integer userId = RequestAttrUtil.getCurrentUserId();
        if(null == userId){
            throw new Exception("用户未登录");
        }

        Integer vehicleId = null;

        //应保养信息
        MaintenanceDto maintenanceDto = maintenanceService.getMaintenanceByuserId(userId);
        if(null != maintenanceDto){
            MaintenanceVo maintenanceVo = new MaintenanceVo();
            BeanUtils.copyProperties(maintenanceDto,maintenanceVo);
            CarDto carDto = carService.getCarById(maintenanceDto.getCarId());
            if(null == carDto ){
                throw new Exception("车辆不存在");
            }

            //查询该车辆的提车时间
            OrderDeliveryBizDto orderDeliveryDto = orderBizService.getDelivery(maintenanceDto.getOrderCode());
            if(null == orderDeliveryDto){
                throw new Exception("提车信息为空");
            }
            StoreDto storeDto = storeService.getStoreById(orderDeliveryDto.getStoreId());
            if(null == orderDeliveryDto){
                throw new Exception("门店信息为空");
            }
            vehicleId = carDto.getVehicleId();
            maintenanceVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceDto.getStatus()));
            maintenanceVo.setStoreId(orderDeliveryDto.getStoreId());
            maintenanceVo.setStoreName(storeDto.getShortName());
            maintenanceVo.setDeliveryTime(LocalDateTime.now().minusYears(1).isBefore(orderDeliveryDto.getDeliveryTime())?orderDeliveryDto.getDeliveryTime():LocalDateTime.now().minusYears(1));
            maintenanceVo.setLicencePlate(carDto.getLicencePlate());
            //计算相差天数 (now() - 应保养日期)
            maintenanceVo.setOverMaintainableDate(betweenDay(LocalDate.now(),maintenanceDto.getMaintainableDate().toLocalDate()));
            //调车联网获取当前车辆已行驶里程
            maintenanceVo.setNowMileage(new BigDecimal(getMileageByVin(carDto.getVin())));
            //计算相差里程  (当前行驶里程 - 应保养里程)
            maintenanceVo.setOverMileage(betweenMileage(new BigDecimal(getMileageByVin(carDto.getVin())),maintenanceDto.getMaintainableMileage()));

            maintenanceAppVo.setMaintenanceVo(maintenanceVo);
        }

        //保养历史信息
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        Paged<MaintenanceLogDto> maintenanceLogDtoPaged = maintenanceLogService.getMaintenanceLogAppPage(map,pageNum,pageSize);
        if (null != maintenanceLogDtoPaged && null != maintenanceLogDtoPaged.getList() && maintenanceLogDtoPaged.getList().size() > 0) {
            Paged<MaintenanceLogAppVo> maintenanceLogAppVoPaged = new Paged<>();
            BeanUtils.copyProperties(maintenanceLogDtoPaged,maintenanceLogAppVoPaged);
            List<MaintenanceLogAppVo> maintenanceLogAppVoList = new ArrayList<>();
            MaintenanceLogAppVo maintenanceLogAppVo = null;
            for (MaintenanceLogDto maintenanceLogDto:maintenanceLogDtoPaged.getList()) {
                maintenanceLogAppVo = new MaintenanceLogAppVo();
                BeanUtils.copyProperties(maintenanceLogDto,maintenanceLogAppVo);
                CarDto carDto = carService.getCarById(maintenanceLogDto.getCarId());
                if(null == carDto ){
                    throw new Exception("车辆不存在");
                }
                if(null == vehicleId ){
                    vehicleId = carDto.getVehicleId();
                }
                if(null != maintenanceLogDto.getRejectReason()){
                    maintenanceLogAppVo.setRejectReasonStr(MaintenanceRejectEnum.getName(maintenanceLogDto.getRejectReason()));
                }
                maintenanceLogAppVo.setLicencePlate(carDto.getLicencePlate());
                maintenanceLogAppVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceLogDto.getStatus()));
                maintenanceLogAppVoList.add(maintenanceLogAppVo);
            }
            maintenanceLogAppVoPaged.setList(maintenanceLogAppVoList);
            maintenanceAppVo.setMaintenanceLogAppVoPaged(maintenanceLogAppVoPaged);
        }

        //查询保养配置信息
        if(null != vehicleId){
            MaintenanceConfigDto maintenanceConfigDto = maintenanceConfigService.getMaintenanceConfigByVehicleId(vehicleId);
            maintenanceAppVo.setMaintenanceMileageConfig(maintenanceConfigDto.getMileage());
            maintenanceAppVo.setMaintainableDayConfig(maintenanceConfigDto.getMaintenanceTime());
        }

        return maintenanceAppVo;
    }

    
    @Override
    public MaintenanceAppNewVo getMaintenanceAppVoPageNew(Integer pageNum, Integer pageSize) throws Exception {
    	MaintenanceAppNewVo maintenanceAppVo = new MaintenanceAppNewVo();
        //获取当前登录的用户id
        Integer userId = RequestAttrUtil.getCurrentUserId();
        if(null == userId){
            throw new Exception("用户未登录");
        }

        Integer vehicleId = null;
        //查询用户订单编号
        List<Long> orderCodes = orderBizService.getCarOrderCodeByUser(userId,false);
        if(null == orderCodes || orderCodes.isEmpty()) {
        	return maintenanceAppVo;
        }
        
        //应保养信息
        List<MaintenanceDto> maintenanceDtoList = maintenanceService.getMaintenanceByorderCodes(orderCodes,userId);
        
        if(null != maintenanceDtoList && !maintenanceDtoList.isEmpty()) {
        	List<MaintenanceVo> maintenanceVoList = new ArrayList<>(maintenanceDtoList.size());
        	for (MaintenanceDto maintenanceDto : maintenanceDtoList) {
        		 MaintenanceVo maintenanceVo = new MaintenanceVo();
                 BeanUtils.copyProperties(maintenanceDto,maintenanceVo);
                 CarDto carDto = carService.getCarById(maintenanceDto.getCarId());
                 if(null == carDto ){
                     throw new Exception("车辆不存在");
                 }

                 //查询该车辆的提车时间
                 OrderDeliveryBizDto orderDeliveryDto = orderBizService.getDelivery(maintenanceDto.getOrderCode());
                 if(null == orderDeliveryDto){
                     throw new Exception("提车信息为空");
                 }
                 StoreDto storeDto = storeService.getStoreById(orderDeliveryDto.getStoreId());
                 if(null == orderDeliveryDto){
                     throw new Exception("门店信息为空");
                 }
                 vehicleId = carDto.getVehicleId();
                 maintenanceVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceDto.getStatus()));
                 maintenanceVo.setStoreId(orderDeliveryDto.getStoreId());
                 maintenanceVo.setStoreName(storeDto.getShortName());
                 maintenanceVo.setDeliveryTime(LocalDateTime.now().minusYears(1).isBefore(orderDeliveryDto.getDeliveryTime())?orderDeliveryDto.getDeliveryTime():LocalDateTime.now().minusYears(1));
                 maintenanceVo.setLicencePlate(carDto.getLicencePlate());
                 //计算相差天数 (now() - 应保养日期)
                 maintenanceVo.setOverMaintainableDate(betweenDay(LocalDate.now(),maintenanceDto.getMaintainableDate().toLocalDate()));
                 //调车联网获取当前车辆已行驶里程
                 maintenanceVo.setNowMileage(new BigDecimal(getMileageByVin(carDto.getVin())));
                 //计算相差里程  (当前行驶里程 - 应保养里程)
                 maintenanceVo.setOverMileage(betweenMileage(new BigDecimal(getMileageByVin(carDto.getVin())),maintenanceDto.getMaintainableMileage()));
                 maintenanceVoList.add(maintenanceVo);
			}
        	maintenanceAppVo.setMaintenanceVoList(maintenanceVoList);
        }
       

        //保养历史信息
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        map.put("orderCodes",orderCodes);
        Paged<MaintenanceLogDto> maintenanceLogDtoPaged = maintenanceLogService.getMaintenanceLogAppPage(map,pageNum,pageSize);
        if (null != maintenanceLogDtoPaged && null != maintenanceLogDtoPaged.getList() && maintenanceLogDtoPaged.getList().size() > 0) {
            Paged<MaintenanceLogAppVo> maintenanceLogAppVoPaged = new Paged<>();
            BeanUtils.copyProperties(maintenanceLogDtoPaged,maintenanceLogAppVoPaged);
            List<MaintenanceLogAppVo> maintenanceLogAppVoList = new ArrayList<>();
            MaintenanceLogAppVo maintenanceLogAppVo = null;
            for (MaintenanceLogDto maintenanceLogDto:maintenanceLogDtoPaged.getList()) {
                maintenanceLogAppVo = new MaintenanceLogAppVo();
                BeanUtils.copyProperties(maintenanceLogDto,maintenanceLogAppVo);
                CarDto carDto = carService.getCarById(maintenanceLogDto.getCarId());
                if(null == carDto ){
                    throw new Exception("车辆不存在");
                }
                if(null == vehicleId ){
                    vehicleId = carDto.getVehicleId();
                }
                if(null != maintenanceLogDto.getRejectReason()){
                    maintenanceLogAppVo.setRejectReasonStr(MaintenanceRejectEnum.getName(maintenanceLogDto.getRejectReason()));
                }
                maintenanceLogAppVo.setLicencePlate(carDto.getLicencePlate());
                maintenanceLogAppVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceLogDto.getStatus()));
                maintenanceLogAppVoList.add(maintenanceLogAppVo);
            }
            maintenanceLogAppVoPaged.setList(maintenanceLogAppVoList);
            maintenanceAppVo.setMaintenanceLogAppVoPaged(maintenanceLogAppVoPaged);
        }

        //查询保养配置信息
        if(null != vehicleId){
            MaintenanceConfigDto maintenanceConfigDto = maintenanceConfigService.getMaintenanceConfigByVehicleId(vehicleId);
            maintenanceAppVo.setMaintenanceMileageConfig(maintenanceConfigDto.getMileage());
            maintenanceAppVo.setMaintainableDayConfig(maintenanceConfigDto.getMaintenanceTime());
        }

        return maintenanceAppVo;
    }
    
    @Override
    public Paged<MaintenanceLogAppVo> getMaintenanceLogAppVoPage(Integer pageNum, Integer pageSize) throws Exception {
    	Paged<MaintenanceLogAppVo>  paged = new Paged<>(null, 0, pageSize);
    	
    	//获取当前登录的用户id
        Integer userId = RequestAttrUtil.getCurrentUserId();
        if(null == userId){
            throw new Exception("用户未登录");
        }

    	//查询用户订单编号
        List<Long> orderCodes = orderBizService.getCarOrderCodeByUser(userId,true);
        if(null == orderCodes || orderCodes.isEmpty()) {
        	return paged;
        }
        
        //保养历史信息
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        map.put("orderCodes",orderCodes);
        Paged<MaintenanceLogDto> maintenanceLogDtoPaged = maintenanceLogService.getMaintenanceLogAppPage(map,pageNum,pageSize);
        if (null != maintenanceLogDtoPaged && null != maintenanceLogDtoPaged.getList() && maintenanceLogDtoPaged.getList().size() > 0) {
            BeanUtils.copyProperties(maintenanceLogDtoPaged,paged);
            List<MaintenanceLogAppVo> maintenanceLogAppVoList = new ArrayList<>();
            MaintenanceLogAppVo maintenanceLogAppVo = null;
            for (MaintenanceLogDto maintenanceLogDto:maintenanceLogDtoPaged.getList()) {
                maintenanceLogAppVo = new MaintenanceLogAppVo();
                BeanUtils.copyProperties(maintenanceLogDto,maintenanceLogAppVo);
                CarDto carDto = carService.getCarById(maintenanceLogDto.getCarId());
                if(null == carDto ){
                    throw new Exception("车辆不存在");
                }
                if(null != maintenanceLogDto.getRejectReason()){
                    maintenanceLogAppVo.setRejectReasonStr(MaintenanceRejectEnum.getName(maintenanceLogDto.getRejectReason()));
                }
                maintenanceLogAppVo.setLicencePlate(carDto.getLicencePlate());
                maintenanceLogAppVo.setStatusStr(MaintenanceStatusEnum.getName(maintenanceLogDto.getStatus()));
                maintenanceLogAppVoList.add(maintenanceLogAppVo);
            }
            paged.setList(maintenanceLogAppVoList);
        }
    	return paged;
    }


    private static Long betweenDay(LocalDate now, LocalDate end){

        Long days =  end.until(now, ChronoUnit.DAYS);

        return days>0? days:0;
    }

    private static BigDecimal betweenMileage(BigDecimal now, BigDecimal end){
        BigDecimal days = now.subtract(end);
        int ret =  days.compareTo(BigDecimal.ZERO);
        return ret == -1 ? BigDecimal.ZERO:days;
    }


    /**
     * 根据车架号获取已行驶里程
     *
     * @param vin
     * @return
     */
    private Integer getMileageByVin(String vin) throws Exception {
        Integer mileage = null;
        List<String> vinList = new ArrayList<>();
        vinList.add(vin);

        ResponseResult<Map<String, IovMileageDto>> ret = iovCarService.getMileageByVins(vinList);
        if (ret.getCode().equals(0)) {
            mileage = ret.getData().get(vin).getOdo();
        }
        return mileage;
    }

}
